package turnstile;

import statemap.FSMContext;
import statemap.State;
import statemap.StateUndefinedException;

public class TurnstileContext extends FSMContext {

	private static final long serialVersionUID = 1L;

	public TurnstileContext(Turnstile owner) {
		super(MainMap.Locked);
		_owner = owner;
	}

	public TurnstileContext(Turnstile owner, TurnstileState initState) {
		super(initState);
		_owner = owner;
	}

	public void enterStartState() {
		getState().Entry(this);
		return;
	}

	public void coin() {
		_transition = "coin";
		getState().coin(this);
		_transition = "";
		return;
	}

	public void pass() {
		_transition = "pass";
		getState().pass(this);
		_transition = "";
		return;
	}

	public TurnstileState getState() throws StateUndefinedException {
		if (_state == null) {
			throw (new statemap.StateUndefinedException());
		}
		return ((TurnstileState) _state);
	}

	protected Turnstile getOwner() {
		return (_owner);
	}

	public void setOwner(Turnstile owner) {
		if (owner == null) {
			throw (new NullPointerException("null owner"));
		} else {
			_owner = owner;
		}
		return;
	}

	transient private Turnstile _owner;

	public static abstract class TurnstileState extends State {

		private static final long serialVersionUID = 1L;

		protected TurnstileState(String name, int id) {
			super(name, id);
		}

		protected void Entry(TurnstileContext context) {
		}

		protected void Exit(TurnstileContext context) {
		}

		protected void coin(TurnstileContext context) {
			Default(context);
		}

		protected void pass(TurnstileContext context) {
			Default(context);
		}

		protected void Default(TurnstileContext context) {
			throw (new statemap.TransitionUndefinedException("State: "
					+ context.getState().getName() + ", Transition: "
					+ context.getTransition()));
		}
	}

	static abstract class MainMap {
		public static final MainMap_Locked Locked = new MainMap_Locked(
				"MainMap.Locked", 0);
		public static final MainMap_Unlocked Unlocked = new MainMap_Unlocked(
				"MainMap.Unlocked", 1);
		private static final MainMap_Default Default = new MainMap_Default(
				"MainMap.Default", -1);

		public static MainMap_Locked getLocked() {
			return Locked;
		}

		public static MainMap_Unlocked getUnlocked() {
			return Unlocked;
		}

		public static MainMap_Default getDefault() {
			return Default;
		}
	}

	protected static class MainMap_Default extends TurnstileState {

		private static final long serialVersionUID = 1L;

		protected MainMap_Default(String name, int id) {
			super(name, id);
		}
	}

	private static final class MainMap_Locked extends MainMap_Default {

		private static final long serialVersionUID = 1L;

		private MainMap_Locked(String name, int id) {
			super(name, id);
		}

		protected void coin(TurnstileContext context) {
			Turnstile ctxt = context.getOwner();

			(context.getState()).Exit(context);
			context.clearState();
			try {
				ctxt.unlock();
			} finally {
				context.setState(MainMap.Unlocked);
				(context.getState()).Entry(context);
			}
			return;
		}

		protected void pass(TurnstileContext context) {
			Turnstile ctxt = context.getOwner();
			(context.getState()).Exit(context);
			context.clearState();
			try {
				ctxt.alarm();
			} finally {
				context.setState(MainMap.Locked);
				(context.getState()).Entry(context);
			}
			return;
		}
	}

	private static final class MainMap_Unlocked extends MainMap_Default {

		private static final long serialVersionUID = 1L;

		private MainMap_Unlocked(String name, int id) {
			super(name, id);
		}

		protected void coin(TurnstileContext context) {
			Turnstile ctxt = context.getOwner();

			(context.getState()).Exit(context);
			context.clearState();
			try {
				ctxt.thankyou();
			} finally {
				context.setState(MainMap.Unlocked);
				(context.getState()).Entry(context);
			}
			return;
		}

		protected void pass(TurnstileContext context) {
			Turnstile ctxt = context.getOwner();

			(context.getState()).Exit(context);
			context.clearState();
			try {
				ctxt.lock();
			} finally {
				context.setState(MainMap.Locked);
				(context.getState()).Entry(context);
			}
			return;
		}
	}
}